package com.uinnova.product.eam.service.impl;

import com.binary.core.exception.MessageException;
import com.binary.core.lang.Conver;
import com.binary.core.util.BinaryUtils;
import com.binary.framework.Local;
import com.binary.jdbc.Page;
import com.uinnova.product.eam.comm.bean.DirSettingDTO;
import com.uinnova.product.eam.comm.model.*;
import com.uinnova.product.eam.db.*;
import com.uinnova.product.eam.db.bean.DiagramDirCount;
import com.uinnova.product.eam.model.DiagramDirTree;
import com.uinnova.product.eam.model.DiagramQ;
import com.uinnova.product.eam.model.VcDiagramDirInfo;
import com.uinnova.product.eam.model.VcDiagramInfo;
import com.uinnova.product.eam.service.ICISwitchSvc;
import com.uinnova.product.eam.service.IOperateSettingService;
import com.uinnova.product.eam.service.VcDiagramSvc;
import com.uinnova.product.vmdb.comm.dao.CommDao;
import com.uinnova.product.vmdb.comm.i18n.MessageUtil;
import com.uinnova.product.vmdb.comm.i18n.VerifyType;
import com.uinnova.product.vmdb.comm.model.ci.CCcCi;
import com.uinnova.product.vmdb.comm.model.ci.CcCi;
import com.uinnova.product.vmdb.comm.util.CommUtil;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.cmdb.base.LibType;
import com.uino.bean.permission.base.SysUser;
import com.uino.bean.permission.query.CSysUser;
import com.uino.util.sys.SysUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Deprecated
public class VcDiagramSvcImpl implements VcDiagramSvc {

    @Autowired
    private VcDiagramDao diagramDao;

    @Autowired
    private VcDiagramDirDao diagramDirDao;

    @Autowired
    private VcDiagramEleDao diagramEleDao;

    @Autowired
    private DcCombDiagramDao combDiagramDao;


    @Autowired
    private VcDiagramCiAttrDispDao attrDispDao;


    @Autowired
    private VcDiagramEnshDao diagramEnshDao;


    private final Long sysDomainId = 1L;

    @Autowired
    private CommDao commDao;

    @Autowired
    private IUserApiSvc userApiSvc;

    @Autowired
    private ShareDiagramSvcImpl diagramSvc;

    @Autowired
    private IOperateSettingService operateSettingService;

    @Autowired
    private ICISwitchSvc ciSwitchSvc;

	@Autowired
    private VcDiagramDirRelationDao diagramDirRelationDao;


    @Override
    public List<VcDiagramDir> queryDiagramDirList(Long domainId, CVcDiagramDir cdt, String orders) {
        MessageUtil.checkEmpty(domainId, "domainId");
        cdt = cdt == null ? new CVcDiagramDir() : cdt;
        cdt.setDomainId(domainId);
        return diagramDirDao.selectList(cdt, orders);
    }


    @Override
    public DiagramDirTree queryDiagramTree(Long domainId, Long userId, Integer dirType, CVcDiagram diagramCdt,
                                           String orders, Boolean flag) {
        MessageUtil.checkEmpty(domainId, "domainId");
        if (BinaryUtils.isEmpty(dirType)) {
            dirType = 1;
        }

        List<DiagramDirTree> retDirList = new ArrayList<DiagramDirTree>();
        CVcDiagramDir cdt = new CVcDiagramDir();
        cdt.setDomainId(domainId);
        cdt.setUserId(userId);
        cdt.setDirType(dirType);
        List<VcDiagramDir> dirs = diagramDirDao.selectList(cdt, orders);
        Set<Long> dirIds = new HashSet<Long>();
        dirIds.add(0L);
        for (VcDiagramDir dir : dirs) {
            dirIds.add(dir.getId());
        }
        List<VcDiagram> diagrams = new ArrayList<VcDiagram>();
        if (flag) {
            if (diagramCdt == null) {
                diagramCdt = new CVcDiagram();
            }
            diagramCdt.setDomainId(domainId);
            diagramCdt.setStatus(1);
            diagramCdt.setDirIds(dirIds.toArray(new Long[0]));
            diagramCdt.setDirType(1);
            diagrams = diagramDao.selectList(diagramCdt, "NAME");
        }

        Map<Long, List<VcDiagram>> diagramDirIdMap = new HashMap<Long, List<VcDiagram>>();
        for (VcDiagram vcDiagram : diagrams) {
            List<VcDiagram> list = diagramDirIdMap.get(vcDiagram.getDirId());
            if (list == null) {
                list = new ArrayList<VcDiagram>();
                diagramDirIdMap.put(vcDiagram.getDirId(), list);
            }
            list.add(vcDiagram);
        }

        Map<Long, DiagramDirTree> dirMap = new HashMap<Long, DiagramDirTree>();
        for (VcDiagramDir diagramDir : dirs) {
            DiagramDirTree dirTree = new DiagramDirTree(diagramDir);
            Long id = diagramDir.getId();
            dirTree.setDiagrams(diagramDirIdMap.get(id));
            dirMap.put(id, dirTree);
        }

        for (VcDiagramDir diagramDir : dirs) {
            DiagramDirTree pDirTree = dirMap.get(diagramDir.getParentId());
            DiagramDirTree dirTree = dirMap.get(diagramDir.getId());

            if (pDirTree != null) {
                List<DiagramDirTree> children = pDirTree.getChildren();
                if (children == null) {
                    children = new ArrayList<DiagramDirTree>();
                    pDirTree.setChildren(children);
                }
                children.add(dirTree);
            } else {
                retDirList.add(dirTree);
            }
        }

        DiagramDirTree ret = new DiagramDirTree(new VcDiagramDir());
        ret.setChildren(retDirList);
        ret.setDiagrams(diagramDirIdMap.get(0L));
        return ret;
    }

    @Override
    public DiagramDirTree queryDiagramTreeByDirRelation(Long domainId, Long userId, Integer dirType,
                                                        CVcDiagram diagramCdt, String orders, Boolean flag) {
        MessageUtil.checkEmpty(domainId, "domainId");
        if (BinaryUtils.isEmpty(dirType)) {
            dirType = 1;
        }

        List<DiagramDirTree> retDirList = new ArrayList<DiagramDirTree>();
        CVcDiagramDir cdt = new CVcDiagramDir();
        cdt.setDomainId(domainId);
        cdt.setUserId(userId);
        cdt.setDirType(dirType);
        List<VcDiagramDir> dirs = diagramDirDao.selectList(cdt, orders);
        Set<Long> dirIds = new HashSet<Long>();
        dirIds.add(0L);
        for (VcDiagramDir dir : dirs) {
            dirIds.add(dir.getId());
        }
        List<VcDiagram> diagrams = new ArrayList<VcDiagram>();
        Map<Long, List<VcDiagram>> diagramDirIdMap = new HashMap<Long, List<VcDiagram>>();
        if (flag) {
            if (diagramCdt == null) {
                diagramCdt = new CVcDiagram();
            }
            if (dirType.equals(1)) {
                diagramCdt.setDomainId(domainId);
                diagramCdt.setStatus(1);
                diagramCdt.setDirIds(dirIds.toArray(new Long[0]));
                diagramCdt.setDirType(dirType);
                diagrams = diagramDao.selectList(diagramCdt, "NAME");
                if (!BinaryUtils.isEmpty(diagrams)) {
                    diagramDirIdMap = BinaryUtils.toObjectGroupMap(diagrams, "dirId");
                }
            } else {
                CVcDiagramDirRelation dirRltCdt = new CVcDiagramDirRelation();
                dirRltCdt.setDirType(dirType);
                dirRltCdt.setDirIds(dirIds.toArray(new Long[0]));
                List<VcDiagramDirRelation> diagramDirRelations = diagramDirRelationDao.selectList(dirRltCdt, null);

                Set<Long> dids = new HashSet<Long>();
                for (VcDiagramDirRelation relation : diagramDirRelations) {
                    Long diagramId = relation.getDiagramId();
                    dids.add(diagramId);
                }
                diagramCdt.setDomainId(domainId);
                diagramCdt.setStatus(1);
                if (!BinaryUtils.isEmpty(diagramCdt.getIds())) {
                    dids.retainAll(Arrays.asList(diagramCdt.getIds()));
                }
                if (!BinaryUtils.isEmpty(dids)) {
                    diagramCdt.setIds(dids.toArray(new Long[0]));
                    diagrams = diagramDao.selectList(diagramCdt, "NAME");
                    if (!BinaryUtils.isEmpty(diagrams)) {
                        Map<Long, VcDiagram> idDiagramMap = BinaryUtils.toObjectMap(diagrams, "id");
                        Set<Long> diagrmIds = new HashSet<Long>();
                        for (VcDiagramDirRelation relation : diagramDirRelations) {
                            Long dirId = relation.getDirId();
                            Long diagramId = relation.getDiagramId();
                            VcDiagram vcDiagram = idDiagramMap.get(diagramId);
                            if (vcDiagram != null) {
                                List<VcDiagram> list = diagramDirIdMap.get(dirId);
                                if (list == null) {
                                    list = new ArrayList<VcDiagram>();
                                    diagramDirIdMap.put(dirId, list);
                                }

                                if (!diagrmIds.contains(vcDiagram.getId())) {
                                    diagrmIds.add(vcDiagram.getId());
                                    list.add(vcDiagram);
                                }
                            }
                        }
                    }
                }
            }
        }

        Map<Long, DiagramDirTree> dirMap = new HashMap<Long, DiagramDirTree>();
        for (VcDiagramDir diagramDir : dirs) {
            DiagramDirTree dirTree = new DiagramDirTree(diagramDir);
            Long id = diagramDir.getId();
            dirTree.setDiagrams(diagramDirIdMap.get(id));
            dirMap.put(id, dirTree);
        }

        for (VcDiagramDir diagramDir : dirs) {
            DiagramDirTree pDirTree = dirMap.get(diagramDir.getParentId());
            DiagramDirTree dirTree = dirMap.get(diagramDir.getId());

            if (pDirTree != null) {
                List<DiagramDirTree> children = pDirTree.getChildren();
                if (children == null) {
                    children = new ArrayList<DiagramDirTree>();
                    pDirTree.setChildren(children);
                }
                children.add(dirTree);
            } else {
                retDirList.add(dirTree);
            }
        }

        DiagramDirTree ret = new DiagramDirTree(new VcDiagramDir());
        ret.setChildren(retDirList);
        ret.setDiagrams(diagramDirIdMap.get(0L));
        return ret;
    }

    @Override
    public List<VcDiagramDirInfo> queryDirDiagramCountList(Long domainId, Long[] dirIds, Long userId) {
        MessageUtil.checkEmpty(domainId, "domainId");
        MessageUtil.checkEmpty(dirIds, "dirIds");
        MessageUtil.checkEmpty(userId, "userId");
        List<DiagramDirCount> counts = diagramDao.selectDirDiagramCountList(domainId, dirIds, userId);
        return CommUtil.copy(counts, VcDiagramDirInfo.class);
    }

    @Override
    public List<VcDiagramEle> queryDiagramEleList(Long domainId, CVcDiagramEle cdt, String orders) {
        MessageUtil.checkEmpty(domainId, "domainId");
        cdt = cdt == null ? new CVcDiagramEle() : cdt;
        cdt.setDomainId(domainId);
        return diagramEleDao.selectList(cdt, orders);
    }

    @Override
    public VcDiagramDir queryDiagramDirById(Long domainId, Long dirId) {
        MessageUtil.checkEmpty(dirId, "dirId");
        return diagramDirDao.selectById(dirId);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Long saveOrUpdateSysDiagramDir(long domainId, VcDiagramDir record,LibType libType) {
        Long id = diagramSvc.doSaveOrUpdateDiagramDir(domainId, record);
        CCcCi cCcCi = new CCcCi();
        cCcCi.setCiCode(record.getEsSysId());
        List<CcCi> ccCis = ciSwitchSvc.queryCiList(SysUtil.getCurrentUserInfo().getDomainId(), cCcCi, null, true, libType);
        if (ccCis == null || ccCis.size() <= 0) {
            return id;
        }
        //根据分类id查询文件夹配置---操作设置
        List<DirSettingDTO> dirSettingDTOList = operateSettingService.getDirSettingByClassId( ccCis.get(0).getClassId());
        if (dirSettingDTOList == null || dirSettingDTOList.size() <= 0) {
            return id;
        }
        if (record.getParentId() != null && record.getEsSysId() != null) {
            record.setId(id);
            //下面就是递归创建操作配置下面的文件夹创建
            List<VcDiagramDir> list = new ArrayList<>();
            for (DirSettingDTO dirSettingDTO : dirSettingDTOList) {
                mkDirRecursion(Arrays.asList(dirSettingDTO),record,list);
            }
        }
        return id;
    }

    private void mkDirRecursion(List<DirSettingDTO> parentDirSetting, VcDiagramDir record, List<VcDiagramDir> list) {
        if (parentDirSetting == null || parentDirSetting.size() <= 0) {
            return;
        }
        for (DirSettingDTO dirSettingDTO : parentDirSetting) {
            VcDiagramDir dir = new VcDiagramDir();
            BeanUtils.copyProperties(record, dir);
            dir.setParentId(record.getId());
            dir.setDirName(dirSettingDTO.getDirName());
            dir.setId(null);
            dir.setSysDir(3);
            list.add(dir);
            Long id = diagramSvc.doSaveOrUpdateDiagramDir(SysUtil.getCurrentUserInfo().getDomainId(), dir);
            dir.setId(id);
            mkDirRecursion(dirSettingDTO.getChildNode(),dir,list);
        }
    }


    @Override
    public Long saveOrUpdateDiagramDir(Long domainId, VcDiagramDir record) {
        Long id = diagramSvc.doSaveOrUpdateDiagramDir(domainId, record);
        /*if (record.getDirType() == 11 && record.getParentId() == 1 && record.getEsSysId() != null) {
            record.setId(id);
            List<VcDiagramDir> list = new ArrayList<>(4);
            list.add(sysDir("应用架构", record));
            list.add(sysDir("业务架构", record));
            list.add(sysDir("数据架构", record));
            list.add(sysDir("技术架构", record));

            for (VcDiagramDir vcDiagramDir : list) {
                doSaveOrUpdateDiagramDir(domainId, vcDiagramDir);
            }
        }*/
        return id;
    }

    private VcDiagramDir sysDir(String dirName, VcDiagramDir record) {
        VcDiagramDir dir = new VcDiagramDir();
        BeanUtils.copyProperties(record, dir);
        dir.setParentId(record.getId());
        dir.setDirName(dirName);
        dir.setId(null);
        dir.setSysDir(0);
        return dir;
    }

    /*@Transactional(rollbackFor = RuntimeException.class)
    public Long doSaveOrUpdateDiagramDir(Long domainId, VcDiagramDir record) {
        MessageUtil.checkEmpty(domainId, "domainId");
        MessageUtil.checkEmpty(record, "record");
        MessageUtil.checkEmpty(record.getParentId(), "parentId");
        MessageUtil.checkEmpty(record.getUserId(), "UserId");
        record.setDomainId(domainId);
        if (record.getParentId() != 0 && record.getParentId() != 1) {
            VcDiagramDir parentVcDiagramDir = diagramDirDao.selectById(record.getParentId());
            if (parentVcDiagramDir.getDirLvl() >= 10) {
                throw new MessageException("文件夹层级超过十级");
            }
        }
        if (BinaryUtils.isEmpty(record.getDirType())) {
            record.setDirType(1);
        }

		Long userId = record.getUserId();
		Long parentId = record.getParentId();
		Integer dirType = record.getDirType();

        VcDiagramDir parent = null;
        if (record.getParentId().longValue() != 0 && record.getParentId() != 1) {
            parent = queryDiagramDirById(domainId, record.getParentId());
            if (parent == null) {
                throw MessageException.i18n("BS_VC_DIR_PARENT_NOT_FIND");
            }
            if (!parent.getUserId().equals(userId)) {
                throw MessageException.i18n("BS_VC_DIR_PARENT_NOT_FIND");
            }
        }

        boolean isadd = record.getId() == null;
        if (isadd) {
            MessageUtil.checkEmpty(record.getDirName(), "dirName");
        } else {
            if (record.getDirName() != null) {
                MessageUtil.checkEmpty(record.getDirName(), "dirName");
            }
        }

        Long id = record.getId();
        if (record.getDirName() != null) {
            String code = record.getDirName().trim();
            record.setDirName(code);

            CVcDiagramDir cdt = new CVcDiagramDir();
            cdt.setDirNameEqual(code);
            cdt.setParentId(parentId);
            cdt.setDomainId(domainId);
            cdt.setUserId(userId);
            cdt.setDirType(dirType);

			List<VcDiagramDir> ls = diagramDirDao.selectList(cdt, null);
			if (ls.size() > 0 && (id == null || ls.size() > 1 || ls.get(0).getId().longValue() != id.longValue())) {
				// MessageUtil.throwVerify(VerifyType.EXIST, "BS_MNAME_DIRNAME", code);
				// MessageUtil.throwVerify(VerifyType.DUPLICATE, "", "");
				// throw MessageException.i18n("BS_MVTYPE_DUPLICATE");
				throw new MessageException("["+record.getDirName()+"]"+ "文件夹已存在");
			}
		}

        boolean isup = record.getId() != null; // 是否是更新操作
        Long oldParentId = null;
        Long newParentId = record.getParentId();

        // 如果当前操作是更新且上级节点有更新, 则获取以前上级ID
        if (isup && newParentId != null) {
            VcDiagramDir old = queryDiagramDirById(domainId, id);
            if (old == null) {
                throw MessageException.i18n("BS_VC_DIR_NOT_FIND");
            }
            oldParentId = old.getParentId();
        }
        id = diagramDirDao.save(record);
        if (isadd) {
            VcDiagramDir updir = new VcDiagramDir();
            if (parent == null) {
                updir.setDirLvl(1);
                updir.setIsLeaf(1);
                updir.setDirPath("#" + id + "#");
            } else {
                updir.setDirLvl(parent.getDirLvl() + 1);
                updir.setIsLeaf(1);
                updir.setDirPath(parent.getDirPath() + id + "#");
                CVcDiagramDir pDir = new CVcDiagramDir();
                // 更新父级文件夹的是否为末级的状态
                parent.setIsLeaf(0);
                diagramDirDao.save(parent);
            }
            diagramDirDao.updateById(updir, id);
        }

        // 如果父级被改变, 则更新所有子节点级别
        if (isup && newParentId != null && !newParentId.equals(oldParentId)) {
            String tableName = diagramDirDao.getDaoDefinition().getTableName();
            String parentFieldName = "PARENT_ID";
            String levelFieldName = "DIR_LVL";
            String pathFieldName = "DIR_PATH";
            String leafFieldName = "IS_LEAF";
            boolean hasDataStatus = diagramDirDao.getDaoDefinition().hasDataStatusField();
            commDao.updateTreeLevel(id, oldParentId, newParentId, tableName, parentFieldName, levelFieldName,
                    pathFieldName, leafFieldName, hasDataStatus);
        }
        return id;
    }
*/
    @Override
    public Integer updateDiagramNameAndDirIdById(Long domainId, String newName, Long newDirId, Long diagramId) {
        MessageUtil.checkEmpty(domainId, "domainId");
        MessageUtil.checkEmpty(diagramId, "diagramId");
        if (newName == null && newDirId == null) {
            return 1;
        }
        VcDiagramInfo diagramInfo = queryDiagramInfoById(domainId, diagramId, new DiagramQ[]{});
        if (diagramInfo == null) {
            MessageUtil.throwVerify(VerifyType.NOT_EXIST, "record", null);
        }
        VcDiagram diagram = diagramInfo.getDiagram();
        newName = newName == null ? diagram.getName() : newName;
        newDirId = newDirId == null ? diagram.getDirId() : newDirId;

        if (newDirId != 0) {
            VcDiagramDir diagramDir = queryDiagramDirById(domainId, newDirId);
            if (diagramDir == null) {
                MessageUtil.throwVerify(VerifyType.NOT_EXIST, "diagramDir", null);
            }
        }

        VcDiagram record = new VcDiagram();
        record.setDirId(newDirId);
        record.setName(newName);
        try {
            String searchField = diagram.getSearchField();
            if (searchField != null && searchField.indexOf(CommUtil.INDEX_SPLIT) > 0) {
                searchField = newName
                        + searchField.substring(searchField.indexOf(CommUtil.INDEX_SPLIT), searchField.length());
            }
            if (searchField == null) {
                searchField = newName;
            }
            record.setSearchField(searchField);
        } catch (Exception e) {
            diagram.setSearchField(newName);
        }
        int result = diagramDao.updateById(record, diagramId);
        Local.commit();
        return result;

    }

    @Override
    public VcDiagramInfo queryDiagramInfoById(Long domainId, Long id, DiagramQ[] diagramQs) {
        MessageUtil.checkEmpty(domainId, "domainId");
        if (BinaryUtils.isEmpty(id)) {
            return null;
        }

        CVcDiagram cdt = new CVcDiagram();
        cdt.setId(id);
        cdt.setDomainId(domainId);
        cdt.setStatus(1);
        List<VcDiagram> datas = diagramDao.selectList(cdt, "ID");
        if (datas.size() == 0) {
            return null;
        }
        return fillDiagramInfo(sysDomainId, domainId, datas, diagramQs).get(0);
    }

    @Override
    public List<VcDiagram> queryDiagramList(Long domainId, CVcDiagram cdt, String orders) {
        MessageUtil.checkEmpty(domainId, "domainId");

        cdt = cdt == null ? new CVcDiagram() : cdt;
        cdt.setDomainId(domainId);
        cdt.setDataStatus(1);

        return diagramDao.selectList(cdt, orders);
    }

    @Override
    public Page<VcDiagramInfo> queryDiagramPageByCdtAndNotInIds(Long domainId, Integer pageNum, Integer pageSize,
                                                                CVcDiagram cdt, Long[] notInIds, String orders,
                                                                DiagramQ[] diagramQs) {
        MessageUtil.checkEmpty(domainId, "domainId");

        cdt = cdt == null ? new CVcDiagram() : cdt;
        cdt.setDomainId(domainId);
        Page<VcDiagram> page = diagramDao.selectPageByCdtAndNotInIds(pageNum, pageSize, notInIds, cdt, orders);
        List<VcDiagramInfo> list = fillDiagramInfo(sysDomainId, domainId, page.getData(), diagramQs);
        return new Page<VcDiagramInfo>(page.getPageNum(), page.getPageSize(), page.getTotalRows(), page.getTotalPages(),
                list);
    }

	@Override
	public Page<VcDiagram> queryDiagramPage(Long domainId, Integer pageNum, Integer pageSize, CVcDiagram cdt,
			String orders) {
		MessageUtil.checkEmpty(domainId, "domainId");

		cdt = cdt == null ? new CVcDiagram() : cdt;
		cdt.setDomainId(domainId);

		return diagramDao.selectPage(pageNum, pageSize, cdt, orders);
	}

	@Override
	public List<VcDiagramInfo> queryDiagramInfoList(Long domainId, CVcDiagram cdt, String orders,
			DiagramQ[] diagramQs) {
		List<VcDiagram> datas = queryDiagramList(domainId, cdt, orders);
		return fillDiagramInfo(sysDomainId, domainId, datas, diagramQs);
	}

    @Override
    public Page<VcDiagramInfo> queryDiagramInfoPage(Long domainId, Integer pageNum, Integer pageSize, CVcDiagram cdt,
                                                    String orders, DiagramQ[] diagramQs) {
        Page<VcDiagram> pageData = queryDiagramPage(domainId, pageNum, pageSize, cdt, orders);
        List<VcDiagramInfo> data = fillDiagramInfo(sysDomainId, domainId, pageData.getData(), diagramQs);

        return new Page<VcDiagramInfo>(pageData.getPageNum(), pageData.getPageSize(), pageData.getTotalRows(),
                pageData.getTotalPages(), data);
    }

	@Override
	public synchronized String generateDiagramName(Long domainId, Long userId, Integer type) {
		CVcDiagram cdt = new CVcDiagram();
		String prefixName = "未命名视图";
		if (type != null && type == 2) {
			cdt.setDiagramType(type);
			prefixName = "未命名组合视图";
		}
		if (type != null && type == 1) {
			cdt.setDiagramTypes(new Integer[] { type, 3 });
		}
		cdt.setStatus(1);
		cdt.setName(prefixName + "%");
		cdt.setUserId(userId);
		cdt.setDomainId(domainId);

		List<VcDiagram> selectList = diagramDao.selectList(cdt, "NAME");
		Set<Integer> used = new HashSet<Integer>();
		for (VcDiagram vcDiagram : selectList) {
			String name = vcDiagram.getName();
			try {
				Integer integer = Conver.to(name.substring(prefixName.length(), name.length()), Integer.class);
				used.add(integer);
			} catch (Exception e) {
				// 失败的是用户自定的名字
			}
		}
		int i = 1;
		for (; i < 100000; i++) {
			if (!used.contains(i)) {
				break;
			}
		}

		return prefixName + i;
	}

	private List<VcDiagramInfo> fillDiagramInfo(Long domainId, Long userDomainId, List<VcDiagram> datas,
			DiagramQ[] diagramQs) {
		List<VcDiagramInfo> ret = new ArrayList<VcDiagramInfo>();
		if (BinaryUtils.isEmpty(datas)) {
			return ret;
		}

		Map<Long, VcDiagramInfo> infoMap = new HashMap<Long, VcDiagramInfo>();
		Set<Long> allDiagramIdSet = new HashSet<Long>();
		Set<Long> creatorIds = new HashSet<Long>();// 作者ID
		// 视图的ID
		Set<Long> dIdSet = new HashSet<Long>();
		// 组合视图的ID
		Set<Long> cdIdSet = new HashSet<Long>();

		for (VcDiagram diagram : datas) {
			Long id = diagram.getId();

			if (diagram.getDiagramType() == null || diagram.getDiagramType() == 1 || diagram.getDiagramType() == 3) {
				dIdSet.add(id);
			} else {
				cdIdSet.add(id);
			}

			allDiagramIdSet.add(id);
			creatorIds.add(diagram.getUserId());

			VcDiagramInfo info = new VcDiagramInfo();
			info.setDiagram(diagram);
			ret.add(info);
			infoMap.put(id, info);
		}
		Long[] dIds = allDiagramIdSet.toArray(new Long[0]);

		SysUser loginUser = SysUtil.getCurrentUserInfo();
		if (!BinaryUtils.isEmpty(loginUser)) {
			Long userId = loginUser.getId();
			CVcDiagramEnsh dEnshCdt = new CVcDiagramEnsh();
			dEnshCdt.setDataStatus(1);
			dEnshCdt.setDomainId(userDomainId);
			dEnshCdt.setUserId(userId);
			List<VcDiagramEnsh> dEnshes = diagramEnshDao.selectList(dEnshCdt, "ID");
			for (VcDiagramEnsh dEnsh : dEnshes) {
				VcDiagramInfo info = infoMap.get(dEnsh.getDiagramId());
				if (!BinaryUtils.isEmpty(info)) {
					info.setIsCollection(1);
				}
			}
		}
		// 追加视图相关的元素
		if (dIdSet.size() > 0) {
			CVcDiagramEle eleCdt = new CVcDiagramEle();
			eleCdt.setDomainId(userDomainId);
			eleCdt.setDiagramIds(dIdSet.toArray(new Long[] {}));
			eleCdt.setEleTypes(new Integer[] { 1, 4, 5, 6 });
			List<VcDiagramEle> dEles = diagramEleDao.selectList(eleCdt, "ID");
			for (VcDiagramEle vcDiagramEle : dEles) {
				Long diagramId = vcDiagramEle.getDiagramId();
				VcDiagramInfo vcDiagramInfo = infoMap.get(diagramId);
				Integer eleType = vcDiagramEle.getEleType();
				if (eleType.intValue() == 5) {
					vcDiagramInfo.setRltRule(vcDiagramEle);
				} else if (eleType.intValue() == 6) {
					vcDiagramInfo.setTemplate(vcDiagramEle);
				} else {
					List<VcDiagramEle> diagramEles = vcDiagramInfo.getDiagramEles();
					if (diagramEles == null) {
						diagramEles = new ArrayList<VcDiagramEle>();
					}
					diagramEles.add(vcDiagramEle);
					vcDiagramInfo.setDiagramEles(diagramEles);
				}
			}
		}

		if (cdIdSet.size() > 0) {
			CDcCombDiagram cdCdt = new CDcCombDiagram();
			cdCdt.setDomainId(userDomainId);
			cdCdt.setCombDiagramIds(cdIdSet.toArray(new Long[] {}));
			List<DcCombDiagram> cdEles = combDiagramDao.selectList(cdCdt, "ID");
			Map<Long, List<DcCombDiagram>> comIdDiagramsMap = BinaryUtils.toObjectGroupMap(cdEles, "combDiagramId");
			for (DcCombDiagram combDiagram : cdEles) {
				Long dId = combDiagram.getCombDiagramId();
				VcDiagramInfo vcDiagramInfo = infoMap.get(dId);

				List<DcCombDiagram> diagrams = comIdDiagramsMap.get(dId);
				if (!BinaryUtils.isEmpty(diagrams)) {
					VcDiagramInfo info = infoMap.get(diagrams.get(0).getDiagramId());
					if (!BinaryUtils.isEmpty(info)) {
						String icon1 = info.getDiagram().getIcon1();
						vcDiagramInfo.getDiagram().setIcon1(icon1);
					}
				}

				List<DcCombDiagram> combDiagrams = vcDiagramInfo.getCombDiagrams();
				if (combDiagrams == null) {
					combDiagrams = new ArrayList<DcCombDiagram>();
					vcDiagramInfo.setCombDiagrams(combDiagrams);
				}
				combDiagrams.add(combDiagram);
			}
		}

		if (!BinaryUtils.isEmpty(diagramQs)) {
			for (DiagramQ diagramQ : diagramQs) {
				if (diagramQ.equals(DiagramQ.CREATOR)) {
					CSysUser cSysUser = new CSysUser();
					cSysUser.setDomainId(domainId);
					cSysUser.setIds(creatorIds.toArray(new Long[] {}));
					cSysUser.setSuperUserFlags(new Integer[] { 0, 1 });
//					List<SysOp> queryList = opSvc.queryList(domainId, userDomainId, cdt, "ID");
					List<SysUser> queryList = userApiSvc.getSysUserByCdt(cSysUser);
					Map<Long, SysUser> userMap = new HashMap<>(queryList.size());
					for (SysUser sysUser : queryList) {
						sysUser.setLoginPasswd(null);
						userMap.put(sysUser.getId(), sysUser);
					}
					for (VcDiagramInfo vcDiagramInfo : ret) {
						Long userId = vcDiagramInfo.getDiagram().getUserId();
						if(userMap.containsKey(userId)){
							vcDiagramInfo.setCreator(userMap.get(userId).clearSensitive());
						}
					}
				}
			}
		}
		return ret;
	}

	@Override
	public Long saveOrUpdateDiagram(Long domainId, VcDiagramInfo diagramInfo) {
		MessageUtil.checkEmpty(domainId, "domainId");
		MessageUtil.checkEmpty(diagramInfo, "record");

		VcDiagram diagram = diagramInfo.getDiagram();
		MessageUtil.checkEmpty(diagram, "record");
		Long userId = diagram.getUserId();

		// 处理关联组合视图关联应用重复的问题
		String appRltCiCode = diagram.getAppRltCiCode();
		if (!BinaryUtils.isEmpty(appRltCiCode)) {
			diagramDao.updateAppRltCiCodeNullByRltCiCode(domainId, appRltCiCode);
		}

		if (diagram.getSubjectId() != 0) {
			// 视图发生改变目录的修改时间也改变
			Long subjectId = diagram.getSubjectId();
			VcDiagramDir record = new VcDiagramDir();
			long modifyTime = BinaryUtils.getNumberDateTime();
			record.setModifyTime(modifyTime);
			diagramDirDao.updateById(record, subjectId);
		}

		Integer diagramType = diagram.getDiagramType();
		if (diagramType == null) {
			diagramType = 1;
			diagram.setDiagramType(1);
		}

		List<Long> combEleIds = new ArrayList<Long>();
		List<DcCombDiagram> combDiagrams = diagramInfo.getCombDiagrams();

		List<VcDiagramTag> diagramTags = new ArrayList<VcDiagramTag>();
		List<VcTag> vcTags = diagramInfo.getTags();
		if (vcTags == null) {
			vcTags = new ArrayList<VcTag>();
		}

		if (diagramType == 2) {
			// 处理组合视图,组合视图图片用第一个元素的做参照
			MessageUtil.checkEmpty(combDiagrams, "combDiagrams");
			for (DcCombDiagram dcCombDiagram : combDiagrams) {
				Long diagramId = dcCombDiagram.getDiagramId();
				MessageUtil.checkEmpty(diagramId, "diagramId");
				combEleIds.add(diagramId);
				dcCombDiagram.setDomainId(domainId);
			}
			// 已第一张视图为参照视图
			VcDiagram sDiagram = diagramDao.selectById(combEleIds.get(0));

			if (sDiagram != null) {
				diagram.setDiagramBgCss(sDiagram.getDiagramBgCss());
				diagram.setDiagramBgImg(
						BinaryUtils.isEmpty(sDiagram.getDiagramBgImg()) ? "" : sDiagram.getDiagramBgImg());
				diagram.setIcon1(sDiagram.getIcon1());
			}
		}

		Long id = diagram.getId();

		boolean isAdd = id == null;

		diagram.setSearchField(generateSearchField(diagram, vcTags));
		Long subjectId = diagram.getSubjectId();
		Integer dirType = diagram.getDirType();
		if (isAdd) {
			Boolean autoName = diagramInfo.getAutoName();
			String name = diagram.getName();
			if (autoName != null && autoName && BinaryUtils.isEmpty(name)) {
				name = generateDiagramName(domainId, userId, diagramType);
			}
			diagram.setName(name);

			// 添加时重新赋值查询字段
			diagram.setSearchField(generateSearchField(diagram, vcTags));

			if (diagramType.equals(1)) {
//				Integer diagramCount = licenseProxy.getLicense().getLimitDiagramCount();

				CVcDiagram dcCdt = new CVcDiagram();
				dcCdt.setDomainId(domainId);
				dcCdt.setDiagramType(1);
				long selectCount = diagramDao.selectCount(dcCdt);
//				if (selectCount >= diagramCount) {
//					// 视图超出授权数量!
//					throw MessageException.i18n("DMV_DIAGRAM_EXCESS_AUTH_QUANTITY");
//				}
				// TODO: 2020/6/19 后续添加
			}

			id = diagramDao.save(diagram);

			if (diagramType.equals(2)) {
				for (DcCombDiagram dcCombDiagram : combDiagrams) {
					dcCombDiagram.setCombDiagramId(id);
				}
				combDiagramDao.saveBatch(combDiagrams);
			}

		} else {
			VcDiagram old = diagramDao.selectById(id);
			// TODO 异常信息国际化
			if (old == null || old.getStatus() == 0) {
				throw MessageException.i18n("DMV_DIAGRAM_NOT_EXIST");
			}
			/*
			 * if(checkEditAuth(domainId, old,
			 * SysUtil.getCurrentUserInfo().getId())==0){ throw
			 * MessageException.i18n("DMV_NOT_AUTH"); }
			 */

			if (diagramType == 2) {
				for (DcCombDiagram dcCombDiagram : combDiagrams) {
					dcCombDiagram.setCombDiagramId(id);
				}

				CDcCombDiagram cdt = new CDcCombDiagram();
				cdt.setDomainId(domainId);
				cdt.setCombDiagramId(id);
				try {
					combDiagramDao.deleteByCdt(cdt);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				combDiagramDao.saveBatch(combDiagrams);
			}

			diagramDao.updateById(diagram, id);
		}

		if (!dirType.equals(1) && !dirType.equals(5) && !dirType.equals(6))
			saveDiagramDirRelation(domainId, subjectId, dirType, id);

		if (diagramType.equals(1) || diagramType.equals(3)) {
			List<VcDiagramEle> diagramEles = diagramInfo.getDiagramEles();
			diagramEles = diagramEles == null ? new ArrayList<VcDiagramEle>() : diagramEles;

			for (VcDiagramEle vcDiagramEle : diagramEles) {
				// TODO 验证
				vcDiagramEle.setDiagramId(id);
				vcDiagramEle.setDomainId(domainId);
			}

			saveDiagramEles(diagramEles, id);

			List<VcDiagramCiAttrDisp> ciAttrDisps = diagramInfo.getCiAttrDisps();
			ciAttrDisps = new ArrayList<VcDiagramCiAttrDisp>();
			for (VcDiagramCiAttrDisp attrDisp : ciAttrDisps) {
				attrDisp.setDiagramId(id);
				attrDisp.setDomainId(domainId);

				Long attrDefId = attrDisp.getAttrDefId();
				String objId = attrDisp.getObjId();
				Integer objType = attrDisp.getObjType();
				MessageUtil.checkEmpty(attrDefId, "attrDefId");
				MessageUtil.checkEmpty(objId, "objId");
				MessageUtil.checkEmpty(objType, "objType");

			}

			if (!isAdd) {
				CVcDiagramCiAttrDisp cdt = new CVcDiagramCiAttrDisp();
				cdt.setDiagramId(id);
				cdt.setDomainId(domainId);

				try {
					attrDispDao.deleteByCdt(cdt);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			if (ciAttrDisps.size() > 0) {
				attrDispDao.saveBatch(ciAttrDisps);
			}

		}
		Local.commit();
		return id;
	}

	@Override
	public VcDiagram updateDiagramBaseInfo(VcDiagram record) {
		MessageUtil.checkEmpty(record, "record");
		MessageUtil.checkEmpty(record.getId(), "id");
		diagramDao.updateById(record, record.getId());
		Local.commit();
		return diagramDao.selectById(record.getId());
	}

    private void saveDiagramEles(List<VcDiagramEle> newEles, Long diagramId) {
        newEles = fixEleList(newEles);
        CVcDiagramEle cdt = new CVcDiagramEle();
        cdt.setDiagramId(diagramId);
        cdt.setEleTypes(new Integer[]{1, 4, 7});
        List<VcDiagramEle> oldEles = diagramEleDao.selectList(cdt, null);

		if (BinaryUtils.isEmpty(oldEles)) {
			diagramEleDao.saveBatch(newEles);
			return;
		}

		Set<Long> removeIds = new HashSet<Long>();
		Map<Long, VcDiagramEle> oldIdEleMap = BinaryUtils.toObjectMap(oldEles, "id");
		Map<Long, VcDiagramEle> newIdEleMap = BinaryUtils.toObjectMap(newEles, "id", true);

		Set<Long> idSet = oldIdEleMap.keySet();
		for (Long id : idSet) {
			VcDiagramEle newEle = newIdEleMap.get(id);
			if (BinaryUtils.isEmpty(newEle))
				removeIds.add(id);
		}
		if (!BinaryUtils.isEmpty(removeIds)) {
			long ids[] = new long[removeIds.size()];
			int i = 0;
			for (Long id : removeIds) {
				ids[i] = id.longValue();
				i++;
			}
			diagramEleDao.deleteBatch(ids);
		}
		List<VcDiagramEle> insertEles = new ArrayList<VcDiagramEle>();
		for (VcDiagramEle newEle : newEles) {
			Long newId = newEle.getId();
			if (BinaryUtils.isEmpty(newId)) {
				insertEles.add(newEle);
			}

		}
		if (!BinaryUtils.isEmpty(insertEles))
			diagramEleDao.saveBatch(insertEles);
	}

	/**
	 * 去除ele中的错误数据
	 */
	private List<VcDiagramEle> fixEleList(List<VcDiagramEle> eles) {
		if (BinaryUtils.isEmpty(eles))
			return eles;
		List<VcDiagramEle> result = new ArrayList<VcDiagramEle>();
		for (VcDiagramEle ele : eles) {
			Long diagramId = ele.getDiagramId();
			String eleId = ele.getEleId();
			String rltDiagramIds = ele.getRltDiagramIds();
			Integer eleType = ele.getEleType();
			if (BinaryUtils.isEmpty(diagramId) || BinaryUtils.isEmpty(eleType)
					|| (BinaryUtils.isEmpty(eleId) && BinaryUtils.isEmpty(rltDiagramIds)))
				continue;
			result.add(ele);
		}
		return result;
	}

	private String generateSearchField(VcDiagram diagram, List<VcTag> vcTags) {
		if (diagram == null) {
            return null;
        }

		StringBuffer searchField = new StringBuffer(1000);
		searchField.append(diagram.getName());
		searchField.append(CommUtil.INDEX_SPLIT);
		searchField.append(SysUtil.getCurrentUserInfo());
		searchField.append(CommUtil.INDEX_SPLIT);

		if (vcTags != null) {
			for (VcTag vcTag : vcTags) {
				searchField.append(vcTag.getTagName());
				searchField.append(CommUtil.INDEX_SPLIT);
			}
		}
		return searchField.toString();
	}


	@Override
	public Map<Long, Set<Long>> queryDiagramDirRelation(Long domainId, CVcDiagramDirRelation cdt) {
		MessageUtil.checkEmpty(domainId, "domainId");
		if (cdt == null) {
            cdt = new CVcDiagramDirRelation();
        }
		Map<Long, Set<Long>> res = new HashMap<Long, Set<Long>>();
		cdt.setDomainId(domainId);
		List<VcDiagramDirRelation> list = diagramDirRelationDao.selectList(cdt, null);
		if (BinaryUtils.isEmpty(list)) {
            return res;
        }
		for (VcDiagramDirRelation record : list) {
			Set<Long> set = res.get(record.getDirId());
			if (set == null) {
				set = new HashSet<Long>();
				res.put(record.getDirId(), set);
			}
			set.add(record.getDiagramId());
		}
		return res;
	}

	@Override
	public Long saveDiagramDirRelation(Long domainId, Long dirId, Integer dirType, Long diagramId) {
		MessageUtil.checkEmpty(domainId, "domainId");
		MessageUtil.checkEmpty(dirId, "dirId");
		MessageUtil.checkEmpty(dirType, "dirType");
		MessageUtil.checkEmpty(diagramId, "diagramId");
		VcDiagramDirRelation record = new VcDiagramDirRelation();
		record.setDomainId(domainId);
		record.setDiagramId(diagramId);
		record.setDirType(dirType);
		record.setDirId(dirId);

		CVcDiagramDirRelation cdt = new CVcDiagramDirRelation();
		cdt.setDomainId(domainId);
		cdt.setDiagramId(diagramId);
		cdt.setDirId(dirId);
		cdt.setDirType(dirType);
		List<VcDiagramDirRelation> list = diagramDirRelationDao.selectList(cdt, null);
		if (!BinaryUtils.isEmpty(list)) {
			record.setId(list.get(0).getId());
		}
		return diagramDirRelationDao.save(record);

	}

	private Integer checkHierarchy(List<VcDiagramDir> selectList) {
		Integer first = 0;
		Integer last = 0;
		for (VcDiagramDir vcDiagramDir:selectList) {
			Long id = vcDiagramDir.getId();
			CVcDiagramDir cVcDiagramDir = new CVcDiagramDir();
			cVcDiagramDir.setDirPath("%#" + id + "%");
			List<VcDiagramDir> childDirs = diagramDirDao.selectList(cVcDiagramDir, "DIR_LVL DESC");
			first = vcDiagramDir.getDirLvl();

			for (VcDiagramDir vcDiagramDir1:childDirs) {
				last = vcDiagramDir1.getDirLvl();
				break;
			}

        }
        return last - first + 1;
    }
}
